<script setup lang="ts">
import type { CSSProperties } from 'vue'
import { javascript } from '@codemirror/lang-javascript'
import { oneDark } from '@codemirror/theme-one-dark'
import { Codemirror } from 'vue-codemirror'

interface Props {
  codeStyle?: CSSProperties // 代码样式
  dark?: boolean // 是否暗黑主题
  autoDestroy?: boolean // 组件销毁时是否自动销毁代码编辑器实例
}
const props = withDefaults(defineProps<Props>(), {
  codeStyle: () => ({
    height: '300px',
    width: '100%',
  }),
  dark: true,
  tabSize: 1,
})

const emits = defineEmits(['ready', 'change', 'focus', 'blur'])

const code = defineModel<any>(
  {
    default: '',
  },
)

const extensions = props.dark ? [javascript(), oneDark] : [javascript()]
function handleReady(payload: any) {
  emits('ready', payload)
}
function onChange(value: string, viewUpdate: any) {
  emits('change', value, viewUpdate)
}
function onFocus(viewUpdate: any) {
  emits('focus', viewUpdate)
}
function onBlur(viewUpdate: any) {
  emits('blur', viewUpdate)
}
</script>

<template>
  <Codemirror
    v-model="code"
    :style="codeStyle"
    :extensions="extensions"
    v-bind="$attrs"
    @ready="handleReady"
    @change="onChange"
    @focus="onFocus"
    @blur="onBlur"
  />
</template>

<style lang="less">
@themeColor: #165dff;
:deep(.cm-editor) {
  border-radius: 8px;
  outline: none;
  border: 1px solid transparent;
  .cm-scroller {
    border-radius: 8px;
  }
}
:deep(.cm-focused) {
  border: 1px solid fade(@themeColor, 48%);
}
</style>
